﻿using System;
using System.Drawing;

/// <summary>
/// 日志系统
/// </summary>
namespace Utils
{
    /// <summary>
    /// 日志等级
    /// </summary>
    public enum LOG_LEVEL
    {
        /// <summary>
        /// 错误日志
        /// </summary>
        LOG_ERROR,

        /// <summary>
        /// 警告日志
        /// </summary>
        LOG_WARNING,

        /// <summary>
        /// 调试信息日志
        /// </summary>
        LOG_DEBUG,

        /// <summary>
        /// 详细信息日志
        /// </summary>
        LOG_DETAILS,
    };

    /// <summary>
    /// 通用log类，用于输出日志
    /// </summary>
    public class SmartLoger
    {
        /// <summary>
        /// 日志颜色对照表
        /// </summary>
        private static readonly Color[] LogColorMap = { Color.Red, Color.Orange, Color.Green, Color.Black };

        /// <summary>
        /// 定义一个输出调试信息的委托，用于用户重定向输出控件
        /// color - 颜色
        /// str   - 字符串
        /// </summary>
        /// <param name="color"></param>
        /// <param name="str"></param>
        public delegate void LogOutDelegate(Color color, String str);

        /// <summary>
        /// 委托对象，用来指向用户的委托函数
        /// </summary>
        private LogOutDelegate LogOutput = null;

        /// <summary>
        /// LOG等级，用于控制输出等级，只有低于此等级的才会被显示出来
        /// </summary>
        private LOG_LEVEL LogLevel = LOG_LEVEL.LOG_DEBUG;

        /// <summary>
        /// 构造函数
        /// level - 日志显示等级，超过此等级的不显示
        /// lod - 委托方法
        /// </summary>
        /// <param name="level"></param>
        public SmartLoger(LOG_LEVEL level, LogOutDelegate lod)
        {
            LogLevel = level;
            LogOutput = lod;
        }

        /// <summary>
        /// 输出日志信息
        /// level - 日志等级
        /// str - 字符串信息
        /// </summary>
        private void LogInfo(LOG_LEVEL level, String str)
        {
            if (level <= LogLevel)
            {
                DateTime time = DateTime.Now;
                LogOutput.BeginInvoke(LogColorMap[(int)level], time.ToString("[HH:mm:ss ") + time.Millisecond.ToString("D3") + "] " + str + "\r\n", null, null);
            }
        }

        /// <summary>
        /// 错误日志
        /// </summary>
        /// <param name="str"></param>
        public void LogError(String str)
        {
            LogInfo(LOG_LEVEL.LOG_ERROR, str);
        }

        /// <summary>
        /// 警告日志
        /// </summary>
        /// <param name="str"></param>
        public void LogWarning(String str)
        {
            LogInfo(LOG_LEVEL.LOG_WARNING, str);
        }

        /// <summary>
        /// 调试日志
        /// </summary>
        /// <param name="str"></param>
        public void LogDebug(String str)
        {
            LogInfo(LOG_LEVEL.LOG_DEBUG, str);
        }

        /// <summary>
        /// 详细信息日志
        /// </summary>
        /// <param name="str"></param>
        public void LogDetails(String str)
        {
            LogInfo(LOG_LEVEL.LOG_DETAILS, str);
        }

        /// <summary>
        /// 输出数组信息
        /// </summary>
        private void LogBuf(LOG_LEVEL level, byte[] buf, int size)
        {
            if (level <= LogLevel)
            {
                Color color = LogColorMap[(int)level];
                DateTime time = DateTime.Now;
                LogOutput.Invoke(color, time.ToString("[yyyy-MM-dd HH:mm:ss ") + time.Millisecond.ToString("D3") + "] ");
                for (int i = 0; i < size; i++)
                {
                    LogOutput.Invoke(color, buf[i].ToString("X2") + " ");
                }
                LogOutput.Invoke(color, "\r\n");
            }
        }

        /// <summary>
        /// 错误数组日志
        /// </summary>
        /// <param name="buf"></param>
        /// <param name="size"></param>
        public void LogBufError(byte[] buf, int size)
        {
            LogBuf(LOG_LEVEL.LOG_ERROR, buf, size);
        }

        /// <summary>
        /// 警告数组日志
        /// </summary>
        /// <param name="buf"></param>
        /// <param name="size"></param>
        public void LogBufWarning(byte[] buf, int size)
        {
            LogBuf(LOG_LEVEL.LOG_ERROR, buf, size);
        }

        /// <summary>
        /// 调试数组日志
        /// </summary>
        /// <param name="buf"></param>
        /// <param name="size"></param>
        public void LogBufDebug(byte[] buf, int size)
        {
            LogBuf(LOG_LEVEL.LOG_ERROR, buf, size);
        }

        /// <summary>
        /// 详细数组日志
        /// </summary>
        /// <param name="buf"></param>
        /// <param name="size"></param>
        public void LogBufDetails(byte[] buf, int size)
        {
            LogBuf(LOG_LEVEL.LOG_ERROR, buf, size);
        }
    }
}